---
title: StreamProvider
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import CodeBlock from "@theme/CodeBlock";
import { trimSnippet } from "../../../../../src/components/CodeSnippet";
import streamProvider from "!!raw-loader!/docs/providers/stream_provider/live_stream_chat_provider.dart";
import streamConsumer from "!!raw-loader!/docs/providers/stream_provider/live_stream_chat_consumer.dart";

`StreamProvider` is similar to [FutureProvider] but for [Stream]s instead of
[Future]s.
`FutureProvider` 与 [Provider] 类似，但用在 [Stream] 中而不是 [Future]。

`StreamProvider` 一般用于：

- 监听Firebase或web-sockets
- 每隔几秒重建另一个provider

由于 [Stream] 自然地公开了一种监听更新的方式，一些人可能认为使用 `StreamProvider` 没什么用。
特别是，你可能认为Flutter的 [StreamBuilder]  可以很好地用于监听流，但这是错误的。

在 [StreamBuilder] 上使用 `StreamProvider` 有很多好处：

- 它允许其他provider使用 [ref.watch] 监听流。
- 多亏了 [AsyncValue] ，它能确保加载和错误情况得到正确处理。
- 它消除了必须区分广播流和普通流的需要。
- 它缓存由流发出的最新值，确保如果在事件发出后添加监听器，
  监听器仍然可以立即访问最新的事件。
- 它允许在测试期间通过覆盖 `StreamProvider` 轻松地模拟流。

[ref.watch]: ../concepts/reading#using-refwatch-to-observe-a-provider
[statenotifierprovider]: ./state_notifier_provider
[provider]: ./provider
[futureprovider]: ./future_provider
[asyncvalue]: https://pub.dev/documentation/riverpod/latest/riverpod/AsyncValue-class.html
[future]: https://api.dart.dev/dart-async/Future-class.html
[stream]: https://api.dart.dev/dart-async/Stream-class.html
[stream.periodic]: https://api.dart.dev/stable/2.15.1/dart-async/Stream/Stream.periodic.html
[family]: ../concepts/modifiers/family
[streambuilder]: https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html

## 用法示例：使用套接字的实时聊天

`StreamProvider` 用于处理异步数据流，如视频流、天气广播Api。

<CodeBlock>{trimSnippet(streamProvider)}</CodeBlock>

然后，UI就可以像这样聊天了：

<CodeBlock>{trimSnippet(streamConsumer)}</CodeBlock>
